<?php

class Options
{

  protected static $table = 'options';

  protected static $pk = 'option_id';

  /**
   *
   * @var IRepository
   */
  protected static $repo;

  protected static $options;

  protected static function autoLoad()
  {
    if (is_null(self::$options)) {
      $data = DB::getInstance()->query()->from(self::$table)->where('option_autoload = 1')->execute()->fetchAll();

      foreach ($data as $row) {
        self::$options[$row['option_name']] = $row;
      }
    }

    return self::$options;
  }

  /**
   * Delete an option.
   *
   * @param string $name
   * @return void
   */
  public static function delete($name)
  {
    DB::getInstance()->delete('options', 'option_name = ?')->execute($name);

    self::autoLoad();

    if (isset(self::$options[$name])) {
      unset(self::$options[$name]);
    }
  }

  /**
   * Check if an option exists
   *
   * @param string $name
   * @return boolean
   */
  public static function exists($name)
  {
    self::autoLoad();

    $exists = isset(self::$options[$name]) || self::getRepository()->findCount(array('where' => 'option_name = ?', 'data' => array($name)));

    return (bool) $exists;
  }

  /**
   * If an option does not exist, create it
   *
   * @param string $name
   * @param mixed $value
   * @return boolean true if option was created, false otherwise
   */
  public static function create($name, $value, $autoload = false)
  {
    if (! self::exists($name)) {
      $option = array();
      $option['option_name'] = $name;
      $option['option_value'] = serialize($value);
      $option['option_autoload'] = $autoload ? 1 : 0;

      self::getRepository()->save($option);

      return true;
    }

    return false;
  }

  /**
   * Read an option
   *
   * @param string $name
   * @return Option
   */
  public static function read($name)
  {
    self::autoLoad();

    if (isset(self::$options[$name])) {
      $option = self::$options[$name];
    }
    else {
      $option = DB::getInstance()->query()->from(self::$table)->where('option_name = ?')->execute($name)->fetchRow();
    }

    return $option;
  }

  /**
   * Read an option and return it's value
   *
   * @param string $name
   * @param mixed $default default return value if option does not exist
   * @return mixed
   */
  public static function value($name, $default = null)
  {
    $option = self::read($name);

    if (empty($option)) {
      return $default;
    }

    return unserialize($option['option_value']);
  }

  /**
   * Create or update an option
   *
   * @param mixed $name option name or instance of Option
   * @param mixed $value
   * @return Option
   */
  public static function update($name, $value = null)
  {
    $args = func_get_args();
    $value = sy_get_param($args, 1);

    if (is_array($name)) {
      $option = $name;
    }
    else {
      $option = self::read($name);

      if (! $option) {
        $option = array();
      }

      $option['option_name'] = $name;
      $option['option_value'] = serialize($value);
    }

    $option['option_modified_at'] = date('Y-m-d H:i:s');

    self::getRepository()->save($option);

    return $option;
  }

  /**
   *
   * @return TableDataGateway
   */
  public static function getRepository()
  {
    if (empty(self::$repo)) {
      self::$repo = TableDataGateway::getInstance(self::$table, self::$pk);
    }

    return self::$repo;
  }

}

?>